package edu.ut.ece382c.valloy.parser;

import java.util.Collection;
import java.util.HashMap;
import java.util.Stack;
import java.util.Vector;

import edu.mit.csail.sdg.alloy4.Pos;

public class ModelClassHierarchy {

	private HashMap <String, ValloyClass> hierarchy;	//Map that represents the class tree
	private ModelClassHierarchy parentHierarchy; 		//in case this extends a hierarchy in another module
	private String parentHierarchyClass;
	private ValloyClass root = null;
	
	public ModelClassHierarchy(String rootName) {
		this.hierarchy = new HashMap<String, ValloyClass>();
		//Create the root class
		this.root = new ValloyClass(rootName, null);
		this.hierarchy.put(rootName, this.root);
		this.parentHierarchy=null;
	}
	/*
	public ModelClassHierarchy(ModelClassHierarchy parentHierarchy, String parentHierarchyClass) {
		this.hierarchy = new HashMap<String, ValloyClass>();
		this.root = this.hierarchy.put("Object", new ValloyClass("Object", null));
		this.parentHierarchy = parentHierarchy;
		this.parentHierarchyClass = parentHierarchyClass;
	}
	*/
	
	public ValloyClass add (String child, String parent){
		if (hierarchy.containsKey(child) || !hierarchy.containsKey(parent)) 
			return null;
		else {
			ValloyClass node = new ValloyClass(child, hierarchy.get(parent));
			hierarchy.get(parent).addChild (node);
			hierarchy.put(child, node);
			return node;
		}
	}
	
	public ValloyClass get (String node){
		return hierarchy.get(node);
	}
	
	public ValloyClass  getRoot(){
		return root;
	}
	
	public boolean contains (String node){
		return hierarchy.containsKey(node);
	}
	
	public int size(){
		return hierarchy.size();
	}
	
	public Vector<ModelClassHierarchy> split(String Node){
		Vector<ModelClassHierarchy> allSubHierarchies = new Vector<ModelClassHierarchy>();
		for (ValloyClass newroot: root.getChildren()){
			ModelClassHierarchy newHierarchy = new ModelClassHierarchy(newroot.getName());
			newHierarchy.add(newroot.getName(), null);
			Stack<ValloyClass> children = new Stack<ValloyClass>();
			children.addAll(newroot.getChildren());
			while (!children.empty()){
				ValloyClass child = children.pop();
				newHierarchy.add(child.getName(), child.getParent().getName());
				children.addAll(child.getChildren());
			}
			allSubHierarchies.add(newHierarchy);
		}
		return allSubHierarchies;	
	}
	
	public Vector<ValloyClass> getAll (){
		return new Vector<ValloyClass> (hierarchy.values());
	}
	
	@Override
	public String toString() {
		String buffer = "//Class Hierarchy for Class: " + root.getName() + "\n";
		return root.nodeTreePrint(buffer, 0);
	}
	
	@Override
	protected ModelClassHierarchy clone() {
		//TODO: Implement
		return this;
	}
	
}
